#include "monitor.h"

void NMI_Handler(void)
{
	register unsigned int	i;
	volatile unsigned int	*p_scbr = (volatile unsigned int*)SCB_BASE;

	mon_debug("\n\n********************************************\n");
	mon_debug("\n   NMI - Non-Maskable Interrupt Occurred!\n\n");
	mon_debug("********************************************\n");

	/**  */
	mon_debug("\n    [EXCEPTION] [SYSTEM CONTROL BLOCK]\n\n");
	for( i = 0;i < ( sizeof(mml_scbr_regs_t) / sizeof(unsigned int) );i++ )
	{
		mon_debug("    @ 0x%08x = 0x%08x\n", &p_scbr[i], p_scbr[i]);
	}
	
	mon_debug("\n********************************************\n");
	mon_debug("\tResetting device now...\n");
	mon_debug("********************************************\n\n");		
  
	/** Now reset platform */
  	mml_reset_system();
	
	return;
}

static void monitor_ack_drs(void)
{
	unsigned int value, secalm, secdiag;

	/** Read secure monitor status */
	IO_READ_U32(SECMON_EXTSC, value);
	mon_debug("External sensors registers: 0x%08X\n", value);
	IO_READ_U32(SECMON_INTSC, value);
	mon_debug("Internal sensors registers: 0x%08X\n", value);
	IO_READ_U32(SECMON_SECALM, secalm);
	mon_debug("Security alarm registers: 0x%08X\n", secalm);
	IO_READ_U32(SECMON_SECDIAG, secdiag);
	mon_debug("Security diagnostic registers: 0x%08X\n", secdiag);

	/** Acknowledge security DRS (if any) */
	if( secdiag != 0x00000100)
	{
		mon_debug("DRS has been detected\n");
		mon_debug("DRS acknowledge\n");
		IO_READ_U32(SECMON_SECALM, secalm);
		mon_debug("Security alarm registers: 0x%08X\n", secalm);
		IO_READ_U32(SECMON_SECDIAG, secdiag);
		mon_debug("Security diagnostic registers: 0x%08X\n\n", secdiag);
		IO_READ_U32(SECMON_DLRTC, value);
		mon_debug("RTC log on DRS event: 0x%08X\n\n", value);
	}
}

static u8 monitor_cfg(void)
{
	SYSP_ST *sysp = NULL;
	u8 ext_conf, int_conf;

	sysp = sys_para_get();
	if(!sysp){
		mon_debug("[MON] get sys para err!\n");
		return 1;
	}

	// external monitor
	ext_conf = sysp->ext_conf;
	IO_WRITE_U32(SECMON_EXTSC, 0x8000003F & (ext_conf + LOCK_REG));

	// inter monitor
	int_conf = sysp->int_conf;
	IO_WRITE_U32(SECMON_INTSC, 0x80000007 & (int_conf + LOCK_REG));

	mon_debug("[MON] ext_conf = 0x%x, int_conf = 0x%x\n", ext_conf, int_conf);
	
	return 0;
}

u8 monitor_check(void)
{
	u32 secalm;

	IO_READ_U32(SECMON_SECALM, secalm);
	if (secalm & DRS_ALARM_FLAGS_MASK){
		monitor_ack_drs();
		return 1;
	}
	
	return 0;
}

u8 monitor_init(void)
{
	monitor_cfg();

	return 0;
}


